package com.tfjybj.itoo.teach.provider.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.dmsdbj.itoo.tool.base.service.impl.BaseServicePlusImpl;
import com.dmsdbj.itoo.tool.business.ItooResult;
import com.dmsdbj.itoo.tool.constantutil.YearSemester;
import com.dmsdbj.itoo.tool.itooexception.ItooRuntimeException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tfjybj.itoo.teach.entity.SemesterEntity;
import com.tfjybj.itoo.teach.provider.dao.SemesterDao;
import com.tfjybj.itoo.teach.provider.service.SemesterService;
import com.tfjybj.itoo.teach.template.SemesterTemplate;
import lombok.extern.slf4j.Slf4j;
import org.jplus.hyberbin.excel.utils.ExcelUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.tfjybj.itoo.teach.provider.until.DemoConstants.*;

/**
 * SemesterService接口实现类
 * ${base}表
 *
 * @author 田成荣
 * @version 2.0.0
 * @since 2.0.0 2018-11-14 14:41:55
 */
@Service("semesterService")
@Slf4j
public class SemesterServiceImpl extends BaseServicePlusImpl<SemesterDao, SemesterEntity> implements SemesterService {
	
	//region 模板生成
    @Resource
    private SemesterDao semesterDao;

    @Resource
    private RedisTemplate<String, SemesterTemplate> redisTemplate;

	
	 @Override
    public PageInfo<SemesterEntity> queryByLikeName(String name, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(semesterDao.queryLikeName(name));
    }


    //endregion

    /* **********************************以下为非模板生成的内容********************************* */


    /**
     * 静态区域块获取配置文件的设置的学年学期始末时间参数-井朝 2018年11月14日21:27:22
     */
    private static Properties properties = new Properties();

    static {
        try {
            // 使用ClassLoader加载properties配置文件生成对应的输入流
            // 使用properties对象加载输入流
            properties.load(new InputStreamReader(YearSemester.class.getClassLoader().getResourceAsStream("path.properties"), "UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获得学年学期(包含本学期)-井朝 2018年11月14日20:58:20
     * 例如getYearSemesterList(-1,1),获取结果（2016-2017学年第二学期，2017-2018学年第一学期，2017-2018学年第二学期）.
     *
     * @param startSemester 当前学年学期为0，从当前学年学期开始想获取的之前学年学期的数量
     * @param endSemester   当前学年学期为0，从当前学年学期开始想获取的之后学年学期的数量
     * @return LinkedHashMap<String , String> 学年学期代码-名字map对象
     */

    @Override
    public LinkedHashMap<String, String> getYearSememsterMap(int startSemester, int endSemester) {
        if (startSemester < -100 || startSemester >100 || endSemester < -100 || endSemester>100){
            //调用itoo写的异常类抛出异常
            throw new ItooRuntimeException("输入的参数不合法,参数请输入-100至100之间的数字");
        }else if (startSemester >endSemester){
            throw new ItooRuntimeException("输入的参数不合法,开始数值必须小于结束数值");
        }
        //getInstance往往是static的,单例模式
        Calendar calendar = Calendar.getInstance();
        LinkedHashMap<String , String> map = new LinkedHashMap<>();
        //计算时间差
        int timeSpan = endSemester - startSemester + 1;
        int rate = Integer.parseInt(properties.getProperty("rate"));

        //生成相应年月,每个学期之间默认相差6个月,所以-6计算现在在哪个学期(相应的6个月可以在配置文件中修改)

        for (int i=0;i < timeSpan ;i++){
            calendar.add(Calendar.MARCH,rate * startSemester);
            map.putAll(getCurrentYearSemester(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1));
            startSemester = startSemester+1;
        }

        return map;
    }


    /**
     * 根据当前年份月份获取学年学期 - 井朝 2018年11月15日10:44:26
     *
     * @param currentYear  当前年份
     * @param currentMonth 当前月份
     * @return LinkedHashMap<String , String>
     */
    private LinkedHashMap<String,String> getCurrentYearSemester(int currentYear, int currentMonth) {
        //定义key value值
        String mapKey;
        String mapValue ;
        //获取key对应的value值,解析字符串返回整数
        int firstSemesterEnd = Integer.parseInt(properties.getProperty("firstSemesterEnd"));
        int secondSemesterEnd = Integer.parseInt(properties.getProperty("secondSemesterEnd"));
        String termNameFirst = properties.getProperty("termNameFirst");
        String termNameSecond = properties.getProperty("termNameSecond");
        if (currentMonth >=1 && currentMonth <= firstSemesterEnd){
            mapKey = currentYear -1 + String.valueOf(currentYear)+"1";
            mapValue=currentYear -1 +"-"+currentYear+termNameFirst;
        }else if(currentMonth>=firstSemesterEnd +1 && currentMonth <=secondSemesterEnd){
            mapKey = currentYear -1 +String.valueOf(currentYear)+"2";
            mapValue = currentYear - 1 + "-" + (currentYear) + termNameSecond;
        }else {
            mapKey = currentYear +String.valueOf(currentYear+1)+"1";
            mapValue = currentYear + "-" +(currentYear +1) +termNameFirst;
        }

        LinkedHashMap<String,String>map = new LinkedHashMap();
        map.put(mapKey,mapValue);
        return map;

    }

    /**
     * 查询所有SemesterEntity记录
     *胡泽宽--
     * @return 所有的semester集合
     * @author 胡泽宽
     * @since 2.0.0 2018年11月17日 15:25:08
     */
    @Override
    public PageInfo<SemesterEntity> querySemester(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(semesterDao.querySemester());
    }

    /**
     * 根据学年学期名称或code模糊查询semester
     *胡泽宽--
     * @return 所有的semester集合
     * @author 胡泽宽
     * @since 2.0.0 2018年11月21日 10:17:18
     */
    @Override
    public PageInfo<SemesterEntity> queryLikeNameorCode(String name, Integer pageNum, Integer pageSize) {
        name="%"+name+"%";
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(semesterDao. queryLikeNameorCode(name));
    }

    /**
     * 详细根据学年学期名称或code模糊查询semester
     *胡泽宽--
     * @return 所有的semester集合
     * @author 胡泽宽
     * @since 2.0.0 2018年11月21日 10:17:18
     */
    @Override
    public PageInfo<SemesterEntity> queryLikeNameorCodedetail(String name, Integer isGraduate, Integer isCurrent, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(semesterDao. queryLikeNameorCodedetail(name,isGraduate,isCurrent));
    }

    /**
     * 获得当前学年学期的自增id
     * @return 第一个incremendids
     * @author 胡泽宽
     * @since 2.0.0 2018年11月24日 09:32:03
     */
    @Override
    public int presentId() {
       return semesterDao.presentId();
    }

    /**
     * 获得当前学年学期的前后的几条记录的详细信息
     * @return List<SemesterEntity>
     * @author 胡泽宽
     * @since 2.0.0 2018年11月24日 10:21:53
     */
    @Override
    public List<SemesterEntity> getYearSemesterList(int startSemester, int endSemester) {
        //获得数组
        if(startSemester>endSemester){
            throw new ItooRuntimeException("输入的参数不合法,开始数值必须小于结束数值");
        }else {
            List<Integer> listincremendids=new ArrayList<>();
            Integer persentid= semesterDao.presentId();
            for(Integer i=persentid+startSemester;i<=persentid + endSemester;i++){
                listincremendids.add(i);
            }
            return semesterDao.getYearSemesterList(listincremendids);
        }
    }

    /**
     * 获得当前学年学期的前后的几条记录的详细信息map
     * @return LinkedHashMap<String, String>
     * @author 胡泽宽
     * @since 2.0.0 2018年11月24日 11:01:25
     */
    @Override
    public LinkedHashMap<String, String> getYearSemesterMap(int startSemester, int endSemester) {
        if(startSemester>endSemester){
            throw new ItooRuntimeException("输入的参数不合法,开始数值必须小于结束数值");
        }else{
            //获得数组
            List<Integer> listincremendids=new ArrayList<>();
            Integer persentid= semesterDao.presentId();
            LinkedHashMap<String, String> linkedHashMap=new LinkedHashMap<>();
            for(Integer i=persentid+startSemester;i<=persentid + endSemester;i++){
                listincremendids.add(i);
            }
            List<SemesterEntity> semesterEntities= semesterDao.getYearSemesterList(listincremendids);
            for(SemesterEntity item:semesterEntities){
                linkedHashMap.put(item.getCode(),item.getName());
            }
            return linkedHashMap;
        }
    }

    /**
     * 获得当前学年学期code的前后的几条记录list<string>
     * @return List<String>
     * @author 胡泽宽
     * @since 2.0.0 2018年11月24日 12:24:00
     */
    @Override
    public List<String> getYearSemesterCode(int startSemester, int endSemester) {
        if(startSemester>endSemester){
            throw new ItooRuntimeException("输入的参数不合法,开始数值必须小于结束数值");
        }else{
            //获得数组
            List<Integer> listincremendids=new ArrayList<>();
            Integer persentid= semesterDao.presentId();
            LinkedHashMap<String, String> linkedHashMap=new LinkedHashMap<>();
            for(Integer i=persentid+startSemester;i<=persentid + endSemester;i++){
                listincremendids.add(i);
            }
            return semesterDao.getYearSemesterCode(listincremendids);
        }
    }

    /**
     * 获得当前学年学期name的前后的几条记录list<string>
     * @return List<String>
     * @author 胡泽宽
     * @since 2.0.0 2018年11月24日 12:24:00
     */
    @Override
    public List<String> getYearSemesterName(int startSemester, int endSemester) {
        if(startSemester>endSemester){
            throw new ItooRuntimeException("输入的参数不合法,开始数值必须小于结束数值");
        }else{
            //获得数组
            List<Integer> listincremendids=new ArrayList<>();
            Integer persentid= semesterDao.presentId();
            LinkedHashMap<String, String> linkedHashMap=new LinkedHashMap<>();
            for(Integer i=persentid+startSemester;i<=persentid + endSemester;i++){
                listincremendids.add(i);
            }
            return semesterDao.getYearSemesterName(listincremendids);
        }
    }
    @Override
    public ItooResult exportByNameorCode(HttpServletResponse response, String searchContent ){
        Map<Serializable, Serializable> map = new HashMap<>(16);

        map.put(SHEET_NAME, "学年学期");
        //要导出的字段
        map.put(COLUMNS, new String[]{"code", "name", "isChGraduate", "isChCurrent", "createTime", "operator", "remark"});
        //导出表格的标题
        map.put(TITLE, "学年学期信息");
        map.put(NAME, "学年学期信息表");
        //要导出的数据
        List<SemesterTemplate> semesterTemplates=new ArrayList<>();
        //进行数据库查询
        List<SemesterEntity> semesterEntities=semesterDao. queryLikeNameorCode("%" + searchContent + "%");
        //时间转换成String的格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for(SemesterEntity semesterEntity: semesterEntities){
            SemesterTemplate semesterTemplate=new SemesterTemplate();
            semesterTemplate.setCode(semesterEntity.getCode());//设置学年学期code
            semesterTemplate.setName(semesterEntity.getName());//设置学年学期名
            semesterTemplate.setIsChGraduate( semesterEntity.getIsGraduate()==1?"是":"否");//设置是否毕业
            semesterTemplate.setIsChCurrent( semesterEntity.getIsCurrent()==1?"是":"否");//设置是否当前
            semesterTemplate.setCreateTime( sdf.format(semesterEntity.getCreateTime())); //设置创建时间
            semesterTemplate.setOperator(semesterEntity.getOperator()); //设置操作人
            semesterTemplate.setRemark(semesterEntity.getRemark());  //设置备注
            semesterTemplates.add(semesterTemplate);
        }
        //为空不进行导出
        if(semesterEntities.size()<=0){
            return ItooResult.build(ItooResult.FAIL, "没有要导出的数据！");
        }
        map.put(DATA_LIST, (Serializable) semesterTemplates);
        //导出
        //导出
        try {
            ExcelUtil.exportExcel(map, response);
        } catch (Exception e) {
            log.error("导出失败,未知的异常--" + e);
            return ItooResult.build(ItooResult.FAIL, "导出信息失败！");
        }
        return ItooResult.build(ItooResult.SUCCESS, "导出信息成功！");
    }

    /**
     * 重复添加校验
     *
     * @param name code
     * @return Integer
     * @author 胡泽宽
     * @since 2.0.0 2018年11月25日 14:21:23
     */
    @Override
    public Integer checkSemesterbycodeorname(String name, String code) {
        return semesterDao.checkSemesterbycodeorname(name,code);
    }

    @Override
    public ItooResult exportTemplate(HttpServletResponse response, String searchContent) {
        Map<Serializable, Serializable> map = new HashMap<>(16);

        map.put(SHEET_NAME, "学年学期");
        //要导出的字段
        map.put(COLUMNS, new String[]{"code", "name", "isChGraduate", "isChCurrent","remark"});
        //导出表格的标题
        map.put(TITLE, "学年学期信息");
        map.put(NAME, "学年学期信息表");
        //要导出的数据
        List<SemesterTemplate> semesterTemplates=new ArrayList<>();
        SemesterTemplate semesterTemplate=new SemesterTemplate();
        semesterTemplate.setCode("201520162");//设置学年学期code
        semesterTemplate.setName("2015-2016学年第二学期");//设置学年学期名
        semesterTemplate.setIsChGraduate("否");//设置是否毕业
        semesterTemplate.setIsChCurrent("否");//设置是否当前
        semesterTemplate.setRemark("备注");
        semesterTemplates.add(semesterTemplate);
        map.put(DATA_LIST, (Serializable) semesterTemplates);
        //导出
        //导出
        try {
            ExcelUtil.exportExcel(map, response);
        } catch (Exception e) {
            log.error("导出失败,未知的异常--" + e);
            return ItooResult.build(ItooResult.FAIL, "导出信息失败！");
        }
        return ItooResult.build(ItooResult.SUCCESS, "导出信息成功！");
    }

    /**
     * 批量导入学年学期
     *
     * @param multipartFile 批量导入的文件
     * @param request       请求
     * @param response      响应
     * @return ItooResult 批量导入的结果
     * @author 胡泽宽
     * @since 2.0.0 2018年11月27日 15:56:29
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ItooResult importsemesterByTemplate(MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("UTF-8");
        try {
            //校验文件是否存在
            String fileName = multipartFile.getOriginalFilename();
            if (fileName == null) {
                log.error("导入失败,fileName is null!");
                return ItooResult.build(ItooResult.FAIL, "传入的文件为空！");
            }
            Map<Serializable, Serializable> map = new HashMap<>(4);
            map.put(SHEET_NAME, "学年学期");
            map.put(CLASS, SemesterTemplate.class);
            List<SemesterTemplate> semesterTemplates = ExcelUtil.importExcel(Objects.requireNonNull(fileName), map, request, response);

            if (semesterTemplates.size() == 0) {
                return ItooResult.build(ItooResult.FAIL, "导入的数据为空，请填写！");
            }
            //定义导入的错误数据集合并存redis中形式的<String,TrainingProgramsTemplate>
            List<SemesterTemplate> errorTPTList = new ArrayList<>();
            String errorTPTListId = IdWorker.getIdStr();
            Long size = redisTemplate.opsForZSet().size(errorTPTListId);
            size = size == null ? 0L : size;

            for(SemesterTemplate excelTPT:semesterTemplates){

                if(!this.verify(excelTPT)){
                    SemesterTemplate semesterTemplateTT =new SemesterTemplate();
                    org.springframework.beans.BeanUtils.copyProperties(excelTPT,semesterTemplateTT);
                    errorTPTList.add(semesterTemplateTT);
                    redisTemplate.opsForZSet().add(errorTPTListId,semesterTemplateTT,size+1);
                    continue;
                }
                int x= semesterDao.checkSemesterbycodeorname(excelTPT.getName(),excelTPT.getCode());
                if(x>0){
                    return ItooResult.build("0001","部分导入失败,数据已经重复添加",errorTPTListId);
                }
                SemesterEntity semesterEntity=new SemesterEntity();
                semesterEntity.setId(IdWorker.getIdStr());
                semesterEntity.setIsCurrent(excelTPT.getIsChCurrent()=="是"?1:0);
                semesterEntity.setIsGraduate(excelTPT.getIsChGraduate()=="是"?1:0);
                semesterEntity.setCode(excelTPT.getCode());
                semesterEntity.setName(excelTPT.getName());
                //设置备注
                semesterEntity.setRemark(excelTPT.getRemark());
                this.save(semesterEntity);
            }
            if(errorTPTList.size()>0){
                return ItooResult.build("0001","部分导入失败",errorTPTListId);
            }

        }catch (Exception e){
            return ItooResult.build(ItooResult.FAIL, "导入数据异常！",e);
        }

        return ItooResult.build(ItooResult.SUCCESS, "导入数据成功！");
    }

    @Override
    public List<SemesterEntity> getNextYearSemester() {
        return semesterDao.getNextYearSemester();
    }

    /**
     * 判断导入的信息是否为空
     *
     * @param excelTPT 需要导入的信息
     * @return boolean 导入的字段是否为空
     * @author 胡泽宽
     * @since 2.0.0 2018年11月27日 16:24:25
     * */
    private boolean verify(SemesterTemplate excelTPT) {
        if(StringUtils.isEmpty(excelTPT.getCode())){
            excelTPT.setFailReason("学年学期code未填写");
            log.warn("导入失败，学年学期code未填写，excelFooEntity-{}",excelTPT);
            return false;
        }
        if(StringUtils.isEmpty(excelTPT.getName())){
            excelTPT.setFailReason("学年学期名称未填写");
            log.warn("导入失败，学年学期名称未填写，excelFooEntity-{}",excelTPT);
            return false;
        }
        if(StringUtils.isEmpty(excelTPT.getIsChCurrent())){
            excelTPT.setFailReason("是否当前未填写");
            log.warn("导入失败，是否当前未填写，excelFooEntity-{}",excelTPT);
            return false;
        }
        if(StringUtils.isEmpty(excelTPT.getIsChGraduate())){
            excelTPT.setFailReason("是否毕业未填写");
            log.warn("导入失败，是否毕业未填写，excelFooEntity-{}",excelTPT);
            return false;
        }
        return true;
    }

    @Override
    public List<SemesterEntity> selSemesterId() {
        return   semesterDao.selSemesterId();
    }

}
